package com.budwk.app.sqfw.services.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.jim.SqfwWebSocket;
import com.budwk.app.jim.WebSocketMsgDTO;
import com.budwk.app.popo.service.PopoInterfaceService;
import com.budwk.app.sms.service.CommonSmsService;
import com.budwk.app.sms.service.OpaSmsService;
import com.budwk.app.sms.service.TencentSmsService;
import com.budwk.app.sqfw.component.PushMsgComponent;
import com.budwk.app.sqfw.constants.SqfwWebSocketMsgConstants;
import com.budwk.app.sqfw.dto.TransferServiceRecordDTO;
import com.budwk.app.sqfw.enums.CompleteFlowFileTypeEnum;
import com.budwk.app.sqfw.enums.SupportBusinessTypeEnum;
import com.budwk.app.sqfw.models.Sqfw_completeflow;
import com.budwk.app.sqfw.models.Sqfw_servicerecord;
import com.budwk.app.sqfw.models.Sqfw_workorder;
import com.budwk.app.sqfw.services.*;
import com.budwk.app.sqfw.vo.PopoFriendWorkOrderVO;
import com.budwk.app.sqfw.vo.SqfwWorkOrderVO;
import com.budwk.app.sqfw.vo.TransferMessageVO;
import com.budwk.app.sqfw.vo.pushmsg.PushMsgConfigVo;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysConfigService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.starter.common.constant.RedisConstant;
import com.budwk.starter.database.service.BaseServiceImpl;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.huawei.push.android.BadgeNotification;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.sql.SqlCallback;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@IocBean(args = {"refer:dao"})
public class SqfwWorkorderServiceImpl extends BaseServiceImpl<Sqfw_workorder> implements SqfwWorkorderService {
    public SqfwWorkorderServiceImpl(Dao dao) {
        super(dao);
    }

    @Inject
    private SqfwServicerecordService sqfwServicerecordService;

    @Inject
    private SqfwPoUserService sqfwPoUserService;

    @Inject
    private SysUserService sysUserService;

    @Inject
    private PopoInterfaceService popoInterfaceService;

    @Inject
    private TencentSmsService tencentSmsService;

    @Inject
    private OpaSmsService opaSmsService;

    @Inject
    private RedisService redisService;

    @Inject
    private SysConfigService sysConfigService;

    @Inject
    private SqfwWebSocket sqfwWebSocket;

    @Inject
    private CommonSmsService commonSmsService;

    @Inject
    private SqfwCompleteflowService sqfwCompleteflowService;

    @Inject
    private SqfwPushMsgLogService sqfwPushMsgLogService;

    private final ExecutorService executorService = Executors.newFixedThreadPool(20);

    /**
     * 转发消息
     *
     * @param dto 转发消息dto
     * @return 发送消息数量
     */
    @Override
    public TransferMessageVO transferServiceRecord(TransferServiceRecordDTO dto) {
        return null;
    }

    @Override
    public TransferMessageVO transferServiceRecordNew(TransferServiceRecordDTO dto) {

        String serviceRecordId = dto.getServiceRecordId();
        List<String> toSysUserIdList = dto.getToSysUserIdList();

        TransferMessageVO resultVO = new TransferMessageVO();
        List<String> successSendSysUserIdList = new ArrayList<>();
        resultVO.setSuccessSendCount(-1);
        resultVO.setSuccessSendSysUserIdList(successSendSysUserIdList);

        if (toSysUserIdList.size() == 0) return resultVO;

        Sqfw_servicerecord serviceRecord = sqfwServicerecordService.fetch(serviceRecordId);
        if (serviceRecord == null) return resultVO;

        // 语音通话没有创建人那么就不能发送消息
        if (StringUtils.isBlank(serviceRecord.getCreatedBy())) return resultVO;

        // 如果用户的这一条工单状态已经是1了就不能转发了
        if (StringUtils.isBlank(serviceRecord.getCreatedBy())) return resultVO;

        // 得到上传服务记录的人的工单
        Sqfw_workorder workOrderOfServiceOrder;
        List<Sqfw_workorder> userWorkOrderList = query(Cnd.where("sqfw_id", "=", dto.getServiceRecordId())
                .and("user_id", "=", serviceRecord.getCreatedBy()));
        if (userWorkOrderList.size() > 0) {
            workOrderOfServiceOrder = userWorkOrderList.get(0);
            if (workOrderOfServiceOrder.getWk_grade().equals("1")) return resultVO;
        } else return resultVO;

        // 得到发送人的用户id以及关联信息
        String senderSysUserId = serviceRecord.getCreatedBy();
        Sys_user sendSysUser = sysUserService.getUserById(senderSysUserId);

        List<Sqfw_workorder> sandWorkOrderList = query(Cnd.where("sqfw_id", "=", dto.getServiceRecordId()).and("user_id", "in", toSysUserIdList));
        Set<String> sandSendUserIdSet = sandWorkOrderList.stream().map(Sqfw_workorder::getUser_id).collect(Collectors.toSet());

        if (StringUtils.isBlank(workOrderOfServiceOrder.getFromUserId())) {
            sandSendUserIdSet.remove(workOrderOfServiceOrder.getUser_id());
        }

        List<Sys_user> receiveUserInfoList = sysUserService.query(Cnd.where("id", "in", toSysUserIdList));

        List<String> serviceOrderServiceNameList = Lists.newArrayList();
        List<String> serviceOrderServicePhoneList = Lists.newArrayList();
        for (Sys_user receiveSysUser : receiveUserInfoList) {

            String receiveSysUserId = receiveSysUser.getId();
            String receiveSysUserName = receiveSysUser.getUsername();

            // 如果这个人已经发送过了 那么就不会再次发送 需要兼容能够发送给自己
            boolean newWorkOrderFlag = true;
            Sqfw_workorder workOrder = new Sqfw_workorder();
            if (receiveSysUserId.equals(workOrderOfServiceOrder.getUser_id())) {
                // 如果是自己的情况
                newWorkOrderFlag = false;
                workOrder = workOrderOfServiceOrder;
            }

            // 已经发送过的数据不能再发送
            if (sandSendUserIdSet.contains(receiveSysUserId)) continue;

            serviceOrderServiceNameList.add(receiveSysUser.getUsername());
            serviceOrderServicePhoneList.add(receiveSysUser.getLoginname());

            workOrder.setSqfw_id(serviceRecord.getId());
            workOrder.setWk_status("new");
            workOrder.setWk_priority(workOrderOfServiceOrder.getWk_priority());
            workOrder.setUser_id(receiveSysUserId);
            workOrder.setFromUserId(senderSysUserId);
            workOrder.setToUserId(receiveSysUserId);
            workOrder.setUser_name(receiveSysUserName);
            workOrder.setCreatedBy(senderSysUserId);
            workOrder.setDelflag(false);
            workOrder.setCreateDate(new Date());
            workOrder.setUpdatedAt(new Date());
            workOrder.setServiceType(serviceRecord.getType());

            if (newWorkOrderFlag) {
                workOrder.setWk_grade("1");
                workOrder = insert(workOrder);
            } else updateIgnoreNull(workOrder);

            if (!senderSysUserId.equals(receiveSysUserId)) {
                // 现在还需要发送短信进行通知
                // wzy 2023-12-15 暂时发送短信
                // commonSmsService.sendSms(serviceRecord, workOrder, sendSysUser, receiveSysUser);

                // 使用websocket进行发送消息
                WebSocketMsgDTO msgDTO = new WebSocketMsgDTO(SqfwWebSocketMsgConstants.work_order_created, "工单信息");
                Map<String, Object> relatedParams = Maps.newHashMap();
                relatedParams.put(SqfwWebSocketMsgConstants.service_record_id, serviceRecord.getId());
                relatedParams.put(SqfwWebSocketMsgConstants.service_record_customer_need, serviceRecord.getCustomer_need());
                relatedParams.put(SqfwWebSocketMsgConstants.service_record_customer_name, serviceRecord.getCustomer_name());
                msgDTO.setRelatedParams(relatedParams);
                boolean websocketFlag = sqfwWebSocket.sendMessage(receiveSysUser.getId(), msgDTO);
            }
            successSendSysUserIdList.add(receiveSysUser.getId());

            //发送消息推送
            //获取token
            BadgeNotification badgeNotification = BadgeNotification.builder().setAddNum(1).setBadgeClass("com.dfsjsoft.communityassistant.ui.main.MainActivity").build();

            if (!StringUtils.isNotBlank(receiveSysUser.getId())) {
                continue;
            }
            String toCopyUserId = receiveSysUser.getId();
            Sys_user toCopyUser = sysUserService.fetch(toCopyUserId);
            if (redisService.hgetAll(RedisConstant.PRE + "push:token:" + toCopyUser.getLoginname()).isEmpty()) {
                continue;
            }
            if (redisService.hgetAll(RedisConstant.PRE + "push:token:" + toCopyUser.getLoginname()).get("pushToken").equals("null")) {
                continue;
            }
            if (redisService.hgetAll(RedisConstant.PRE + "push:token:" + toCopyUser.getLoginname()).get("pushToken").equals("")) {
                continue;
            }
            Map<String, String> mapToken = redisService.hgetAll(RedisConstant.PRE + "push:token:" + toCopyUser.getLoginname());
            // 消息推送
            PushMsgConfigVo c = PushMsgComponent.buildPushMsgConfigVo(mapToken, dto.getServiceRecordId(), "msg_assign", JSONObject.toJSONString(badgeNotification));
            sqfwPushMsgLogService.pushMessage(c, null, serviceRecord);
        }

        // 更新服务消息数据
        String newReceiveUserNameStr = Joiner.on(",").join(serviceOrderServiceNameList);
        String newReceiveUserPhoneNoStr = Joiner.on(",").join(serviceOrderServicePhoneList);

        String serviceName = serviceRecord.getService_name();
        serviceName = StringUtils.isBlank(serviceName) ? "" : serviceName;

        String servicePhone = serviceRecord.getService_phone();
        servicePhone = StringUtils.isBlank(servicePhone) ? "" : servicePhone;

        if (StringUtils.isNotBlank(newReceiveUserNameStr)) {
            if (StringUtils.isNotBlank(serviceName))
                newReceiveUserNameStr = serviceName + "," + newReceiveUserNameStr;
            serviceRecord.setService_name(newReceiveUserNameStr);
        }

        if (StringUtils.isNotBlank(newReceiveUserPhoneNoStr)) {
            if (StringUtils.isNotBlank(servicePhone))
                newReceiveUserPhoneNoStr = servicePhone + "," + newReceiveUserPhoneNoStr;
            serviceRecord.setService_phone(newReceiveUserPhoneNoStr);
        }
        sqfwServicerecordService.update(serviceRecord);

        // wzy 2023-5-22 要将服务记录对应的所有的工单的状态
        String preUpdateWkPriority = dto.getWorkOrderWkPriority();
        if (StringUtils.isBlank(preUpdateWkPriority)) preUpdateWkPriority = workOrderOfServiceOrder.getWk_priority();
        update(Chain.make("wk_priority", preUpdateWkPriority), Cnd.where("sqfw_id", "=", dto.getServiceRecordId()));

        resultVO.setSuccessSendCount(successSendSysUserIdList.size());
        resultVO.setSuccessSendSysUserIdList(successSendSysUserIdList);
        return resultVO;
    }

    public Sqfw_workorder queryBySqfwIdAndUserId(String sqfwId, String userId) {
        List<Sqfw_workorder> list = query(Cnd.where("sqfw_id", "=", sqfwId).and("user_id", "=", userId));
        if (list.size() > 0) return list.get(0);
        return null;
    }

    public Sqfw_workorder queryBySqfwIdAndToUserId(String sqfwId, String userId) {
        List<Sqfw_workorder> list = query(Cnd.where("sqfw_id", "=", sqfwId).and("to_user_id", "=", userId));
        if (list.size() > 0) return list.get(0);
        return null;
    }

    @Override
    public List<Sqfw_workorder> queryBySqfwIdAndFromUserId(String sqfwId, String userId) {
        return query(Cnd.where("sqfw_id", "=", sqfwId).and("from_user_id", "=", userId).and("user_id", "!=", userId));
    }

    @Override
    public List<PopoFriendWorkOrderVO> getPopoFriendNotCompleteWorkOrderList(List<String> popoUidList, Boolean workOrderListFlag,
                                                                             String wkStatus, String userId) {
        List<PopoFriendWorkOrderVO> resultList = Lists.newArrayList();
        ConcurrentHashMap<String, PopoFriendWorkOrderVO> resultMap = new ConcurrentHashMap<>();
        if (popoUidList.size() == 0) return resultList;

        Set<String> popoUidSet = Sets.newHashSet(popoUidList);

        CountDownLatch countDownLatch = new CountDownLatch(popoUidSet.size());
        // 首先要查这些popo用户对应的系统用户
        for (String popoUid : popoUidSet) {
            executorService.execute(() -> {
                String sysUserId = sqfwPoUserService.getSysUserIdByPopoUid(popoUid);

                if (StringUtils.isBlank(sysUserId)) {
                    countDownLatch.countDown();
                    return;
                }

                List<Sqfw_workorder> workOrderList = query(Cnd.where("user_id", "=", userId)
                        .and("from_user_id", "=", sysUserId).and("delflag", "=", false).asc("createdat"));

                int completeCount = 0;
                int notCompleteCount = 0;
                List<Sqfw_workorder> workOrderDetailList = Lists.newArrayList();
                for (Sqfw_workorder workOrder : workOrderList) {
                    if (workOrder.getWk_status().equals(wkStatus) && workOrderListFlag) {
                        workOrderDetailList.add(workOrder);
                    }

                    if (workOrder.getWk_status().equals("complete")) completeCount++;
                    if (workOrder.getWk_status().equals("new")) notCompleteCount++;
                }

                PopoFriendWorkOrderVO vo = new PopoFriendWorkOrderVO();
                vo.setPopoUid(popoUid);
                vo.setSysUserId(sysUserId);
                vo.setNotCompleteCount(notCompleteCount);
                vo.setCompleteCount(completeCount);
                vo.setWorkOrderDetailList(workOrderDetailList);

                resultMap.put(vo.getPopoUid(), vo);

                countDownLatch.countDown();
            });
        }

        try {
            countDownLatch.await();
        } catch (Exception e) {
            e.printStackTrace();
        }

        resultMap.forEach((k, v) -> resultList.add(v));
        return resultList;
    }

    @Override
    public List<SqfwWorkOrderVO> getVO(List<Sqfw_workorder> list) {

        List<SqfwWorkOrderVO> collect = list.stream().map(item -> {
            SqfwWorkOrderVO vo = new SqfwWorkOrderVO();
            BeanUtil.copyProperties(item, vo);
            return vo;
        }).collect(Collectors.toList());

        ConcurrentHashMap<String, Sqfw_servicerecord> serviceOrderMap = new ConcurrentHashMap<>();

        CountDownLatch countDownLatch = new CountDownLatch(list.size());
        for (SqfwWorkOrderVO vo : collect) {
            executorService.execute(() -> {
                try {

                    String serviceRecordId = vo.getSqfw_id();
                    if (serviceOrderMap.containsKey(serviceRecordId)) {
                        Sqfw_servicerecord queryServiceRecord = serviceOrderMap.get(serviceRecordId);
                        vo.setServiceOrderTitle(queryServiceRecord.getCustomer_need());
                        vo.setServiceType(queryServiceRecord.getType());
                        vo.setHzqd(queryServiceRecord.getHzqd());
                    } else {
                        Sqfw_servicerecord serviceRecord = sqfwServicerecordService.fetch(serviceRecordId);
                        if (serviceRecord != null) {
                            vo.setServiceOrderTitle(serviceRecord.getCustomer_need());
                            vo.setServiceType(serviceRecord.getType());
                            vo.setHzqd(serviceRecord.getHzqd());
                            serviceOrderMap.put(serviceRecordId, serviceRecord);
                        }
                    }

                    String fromUserId = vo.getFromUserId();
                    String toUserId = vo.getToUserId();

                    Set<String> userIdSet = new HashSet<>();
                    if (StringUtils.isNotBlank(fromUserId)) userIdSet.add(fromUserId);
                    if (StringUtils.isNotBlank(toUserId)) userIdSet.add(toUserId);

                    List<Sys_user> userList = sysUserService.getUserByIds(userIdSet);
                    for (Sys_user sys_user : userList) {
                        if (StringUtils.isNotBlank(fromUserId) && sys_user.getId().equals(fromUserId)) {
                            vo.setFromUserName(sys_user.getUsername());
                            vo.setFromUserPhoneNO(sys_user.getLoginname());
                        }
                        if (StringUtils.isNotBlank(toUserId) && sys_user.getId().equals(toUserId)) {
                            vo.setToUserName(sys_user.getUsername());
                            vo.setToUserPhoneNO(sys_user.getLoginname());
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    countDownLatch.countDown();
                }
            });
        }

        try {
            countDownLatch.await();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return collect;
    }


    /**
     * 任务记录列表查询
     * Add by LJT 2023-10-9
     */
    public List<Sqfw_workorder> queryList(Sqfw_servicerecord bean, Sqfw_servicerecord bo, String userId, String fromUserId) {
        Sql sqlwork = null;
        if (null != fromUserId && "fromUserId" == fromUserId) {
            StringBuffer sb = new StringBuffer();
            sb.append("select t4.* from (");
            sb.append("SELECT t1.*, t2.community FROM ( select t3.* from shequ.Sqfw_workorder t3 where sqfw_id = @sqfwId and from_user_id = @fromUserId) t1 LEFT JOIN shequ.sys_user t2 ON t1.user_id = t2.id");
            if (StringUtils.isNotBlank(bean.getCommunity())) {
                sb.append(") t4 where community  like '%").append(bean.getCommunity()).append("%'");
            } else {
                sb.append(") t4");
            }
            sqlwork = Sqls.create(sb.toString());
            sqlwork.setParam("sqfwId", bo.getId());
            sqlwork.setParam("fromUserId", bo.getCreatedBy());
        }
        if (null != userId && "userId" == userId) {
            StringBuffer sb = new StringBuffer();
            sb.append("select t4.* from (");
            sb.append("SELECT t1.*, t2.community FROM ( select t3.* from shequ.Sqfw_workorder t3 where sqfw_id = @sqfwId and user_id = @userId) t1 LEFT JOIN shequ.sys_user t2 ON t1.user_id = t2.id");
            if (StringUtils.isNotBlank(bean.getCommunity())) {
                sb.append(") t4 where community  like '%").append(bean.getCommunity()).append("%'");
            } else {
                sb.append(") t4");
            }
            sqlwork = Sqls.create(sb.toString());
            sqlwork.setParam("sqfwId", bo.getId());
            sqlwork.setParam("userId", bo.getCreatedBy());
        }
        sqlwork.setCallback(new SqlCallback() {
            public Object invoke(Connection conn, ResultSet rs, Sql sql) throws SQLException {
                ResultSetMetaData metaData = rs.getMetaData();
                int columnCount = metaData.getColumnCount();
                List<Sqfw_workorder> result = new ArrayList<Sqfw_workorder>();
                while (rs.next()) {
                    Sqfw_workorder record = new Sqfw_workorder();
                    for (int i = 1; i <= columnCount; i++) {
                        record.setId(rs.getString("id"));
                        record.setSqfw_id(rs.getString("sqfw_id"));
                        record.setUser_name(rs.getString("user_name"));
                        record.setWk_status(rs.getString("wk_status"));
                        record.setWk_grade(rs.getString("wk_grade"));
                        record.setWk_priority(rs.getString("wk_priority"));
                        record.setComplete_time(rs.getTimestamp("complete_time"));
                        record.setCreatedBy(rs.getString("createdby"));
                        record.setCreateDate(rs.getTimestamp("createdat"));
                        record.setUpdatedBy(rs.getString("updatedby"));
                        record.setUpdatedAt(rs.getTimestamp("updatedat"));
                        record.setDelflag(rs.getBoolean("delflag"));
                        record.setUser_id(rs.getString("user_id"));
                        record.setFromUserId(rs.getString("from_user_id"));
                        record.setToUserId(rs.getString("to_user_id"));
                        record.setRemark(rs.getString("remark"));
                        record.setPopoMid(rs.getString("popo_mid"));
                        record.setLatestFlowRemark(rs.getString("latest_flow_remark"));
                        record.setFlowStartTime(rs.getTimestamp("flow_start_time"));
                        record.setServiceType(rs.getString("service_type"));
                        record.setCommunity(rs.getString("community"));
                    }
                    result.add(record);
                }
                return result;
            }
        });
        this.dao().execute(sqlwork);
        return sqlwork.getList(Sqfw_workorder.class);
    }

    /**
     * 新增工作流和删除工作流的时候会更新工单表中的最新的状态
     *
     * @param workerId 工单id
     * @param fileType 服务类型
     * @param plus     是否需要++操作 设置了plus参数是 该方法中无法确定调用这个方法的地方是否提前进行了新增或者删除操作，会影响统计结果
     */
    @Override
    public void updateLatestFlowRemarkWithCompleteFlow(String workerId, String fileType, boolean plus) {
        if(StrUtil.isEmpty(workerId)){
            return;
        }
        String latestFlowRemark = "";

        // 根据文件类型更新工单最新状态
        if (StringUtils.isNotBlank(fileType)) {
            List<CompleteFlowFileTypeEnum> fileTypeEnumList = Lists.newArrayList(CompleteFlowFileTypeEnum.values());
            for (CompleteFlowFileTypeEnum completeFlowFileTypeEnum : fileTypeEnumList) {
                if (completeFlowFileTypeEnum.getName().equals(fileType)) {
                    latestFlowRemark = completeFlowFileTypeEnum.getWorkOrderLatestRemark();
                    break;
                }
            }
        }

        if (latestFlowRemark != null) {
            // 这个类型是包含
            Set<String> supportBusinessSet = Lists.newArrayList(SupportBusinessTypeEnum.values()).stream().map(SupportBusinessTypeEnum::getName).collect(Collectors.toSet());
            if (supportBusinessSet.contains(fileType)) {
                // 如果是完成了文档需要统计一下当前一共完成了几个文档
                Cnd countCnd = Cnd.NEW();
                countCnd.and(Sqfw_completeflow::getFileType, "=", fileType)
                        .and(Sqfw_completeflow::getWorkerId, "=", workerId);
                int count = sqfwCompleteflowService.count(countCnd);
                if (plus) count++;
                latestFlowRemark = StrFormatter.format("完成了{}份文档", count);
            }

            Sqfw_workorder updateWorkOrder = new Sqfw_workorder();
            updateWorkOrder.setId(workerId);
            updateWorkOrder.setLatestFlowRemark(latestFlowRemark);
            updateIgnoreNull(updateWorkOrder);
        }
    }

    @Override
    public void updateLatestFlowRemarkWithCompleteFlow(Sqfw_workorder workOrder, String latestFlowRemark, String serviceType, boolean plus) {
        String workerId = workOrder.getId();
        if (latestFlowRemark != null) {
            if (latestFlowRemark.equals("完成了文档")) {
                // 如果是完成了文档需要统计一下当前一共完成了几个文档
                Cnd countCnd = Cnd.NEW();
                countCnd.and("file_type", "=", serviceType)
                        .and("worker_id", "=", workerId);
                int count = sqfwCompleteflowService.count(countCnd);
                if (plus) count++;
                latestFlowRemark = StrFormatter.format("完成了{}份文档", count);
            }

            workOrder.setLatestFlowRemark(latestFlowRemark);
            update(workOrder);
        }
    }
}
